package com.yangyouli.unity_demo_server.controller;

import java.util.ArrayList;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.yangyouli.unity_demo_server.annotation.Inject;
import com.yangyouli.unity_demo_server.annotation.ResponseClass;
import com.yangyouli.unity_demo_server.annotation.ResponseMethod;
import com.yangyouli.unity_demo_server.entity.FriendsVO;
import com.yangyouli.unity_demo_server.entity.User;
import com.yangyouli.unity_demo_server.entity.UserData;
import com.yangyouli.unity_demo_server.server.Client;
import com.yangyouli.unity_demo_server.server.serializeModel.EmailCode;
import com.yangyouli.unity_demo_server.server.serializeModel.EmailCodeAndAccount;
import com.yangyouli.unity_demo_server.server.serializeModel.ForgetPwdResetPwd;
import com.yangyouli.unity_demo_server.server.serializeModel.Password;
import com.yangyouli.unity_demo_server.service.FriendsService;
import com.yangyouli.unity_demo_server.service.UserDataService;
import com.yangyouli.unity_demo_server.service.UserService;
import com.yangyouli.unity_demo_server.service.UserVoService;
import com.yangyouli.unity_demo_server.util.Check;
import com.yangyouli.unity_demo_server.util.EmailUtil;
import com.yangyouli.unity_demo_server.util.Generator;
import com.yangyouli.unity_demo_server.util.Page;
import com.yangyouli.unity_demo_server.util.PageWithData;
import com.yangyouli.unity_demo_server.util.ThreadLocalHelper;

@ResponseClass("userController")
public class UserController {
	private static final String SSO_REQUEST_CLASS_NAME = "B-SSOCheckRequest"; 
	
	@Inject
	private UserService userService;
	@Inject
	private UserDataService userDataService;
	@Inject
	private UserVoService userVoService;
	@Inject
	private FriendsService friendsService;
	
	Logger log = Logger.getLogger(UserController.class);
	
	@ResponseMethod
	public String login (String data) {
		try {
			String account = data.substring(0, data.indexOf(","));
			String password = data.substring(data.indexOf(",") + 1, data.length());
			if (account == null || password == null) return "502";
			User user = userService.verifyUser(account, password);
			if (user != null) {
				Client thisClient = ThreadLocalHelper.getClient();
				// 验证是否有用户登陆
				for (Client c : thisClient.getServer().getLoginClients()) {
					if (c.getUserId() == user.getId()) {
						// 已经登陆，给此客户端发送下线请求
						c.sendResponse(SSO_REQUEST_CLASS_NAME, user.getId() + "-" + user.getNickname());
						c.setUserId(0);
						thisClient.getServer().userLogoff(c);
						break;
					}
				}
				// 用户登陆，存储 userId 到 Client
				thisClient.setUserId(user.getId());
				thisClient.getServer().userLogin(thisClient);
				log.info("用户登陆-成功, account:" + account + " password:" + password);
				return "" + user.getId();
			} else {
				log.info("用户登陆-失败, account:" + account + " password:" + password);
				return "0";
			}
		} catch(Exception e1) {
			log.error("登陆错误", e1);
		}
		log.error("系统异常返回-1");
		return "-1"; // 系统错误
	}
	
	@ResponseMethod
	public String register (String data) {
		String account = data.substring(0, data.indexOf(","));
		String password = data.substring(data.indexOf(",") + 1, data.length());
		if (account == null || password == null) return "502";
		int result = userService.registerUser(account, password);
		if (result == 1) {
			log.info("用户注册-成功, account:" + account + " password:" + password);
		} else {
			log.info("用户注册-失败, account:" + account + " password:" + password);
		}
		return String.valueOf(result);
	}
	
	/**
	 * 有玩家下线时调用此方法
	 * @param data
	 * @return 下线的用户 id-名称
	 */
	@ResponseMethod("offline")
	public String offline (String data) {
		Client c = ThreadLocalHelper.getClient();
		int userId = c.getUserId();
		c.getServer().userLogoff(c);
		return userId + "-" + userService.findById(userId).getNickname();
	}
	
	@ResponseMethod("userData")
	public String getUserData (String data) {
		int userId = ThreadLocalHelper.getClient().getUserId();
		return JSONObject.toJSONString(userVoService.findByUserId(userId));
	}
	
	@ResponseMethod("changeHeadImg")
	public void changeHeadImg (String data) {
		int userId = ThreadLocalHelper.getClient().getUserId();
		UserData userData = new UserData();
		userData.setUserId(userId);
		userData.setHeadImgName(data);
		userDataService.updateStringFieldByUserId(userData);
	}
	
	@ResponseMethod("changePwd")
	public String changePwd (String data) {
		int userId = ThreadLocalHelper.getClient().getUserId();
		Password password = JSONObject.parseObject(data, Password.class);
		if (!userService.checkPwd(password.getNewPassword())) {
			return "0"; // 新密码格式不符合规范
		}
		if (userService.changePassowrd(userId, password.getNewPassword(), password.getOldPassword())) {
			return "1"; // 修改密码成功
		}
		return "-1"; // 旧密码错误，修改密码失败
	}
	
	@ResponseMethod("changeNickname")
	public String changeNickname (String data) {
		if (!userService.checkNickname(data)) {
			return "-1";
		}
		int userId = ThreadLocalHelper.getClient().getUserId();
		User user = new User();
		user.setId(userId);
		user.setNickname(data);
		userService.UpdateExcludeEmail(user);
		return "1";
	}
	
	String title = "【验证码】生化迷城";
	String content = "你的验证码为：%s，有效期十分钟。如不是本人操作，请忽视或删除本邮件。<br><br>祝游戏愉快！";
	@ResponseMethod("sendMail")
	public String sendMail (String data) {
		String email = data;
		if (!Check.isEmailAddress(email)) {
			return "-1";
		}
		String code = Generator.generateNumberCode(6);
		boolean isAddSucc = ThreadLocalHelper.getClient().getServer()
				.addVerifcationCode(email, code);
		if (!isAddSucc) {
			return "0";
		}
		EmailUtil.sendMail(email, title, String.format(content, code));
		return "1";
	}
	
	@ResponseMethod("sendMailWithUserId")
	public String sendMailWithUserId (String data) {
		String email = data;
		if (!Check.isEmailAddress(email)) {
			return "-1";
		}
		String code = Generator.generateNumberCode(6);
		boolean isAddSucc = ThreadLocalHelper.getClient().getServer()
				.addVerifcationCode(email, code);
		if (!isAddSucc) {
			return "0";
		}
		EmailUtil.sendMail(email, title, String.format(content, code));
		return "1";
	}
	
	/**
	 * 绑定邮箱 -2：已经绑定了邮箱，不能再次绑定， -1：验证码错误，1：绑定成功
	 * @param data
	 * @return
	 */
	@ResponseMethod("bindEmail")
	public String bindEmail (String data) {
		EmailCode emailCode = JSONObject.parseObject(data, EmailCode.class);
		String rightCode = ThreadLocalHelper.getClient().getServer()
				.getCodeByEmail(emailCode.getEmail());
		if (rightCode == null || !emailCode.getInputCode().equals(rightCode)) {
			return "-1";
		}
		User user = userService.findById(ThreadLocalHelper.getClient().getUserId());
		if (user.getMail() != null && !user.getMail().isEmpty()) {
			return "-2";
		}
		user.setMail(emailCode.getEmail());
		userService.UpdateEmail(user);
		// 移除验证码
		ThreadLocalHelper.getClient().getServer().removeVerificationCode(user.getMail());
		return "1";
	}
	
	/**
	 * 解绑邮箱 -2：未绑定该邮箱，-1：验证码错误，1：解绑成功
	 * @param data
	 * @return
	 */
	@ResponseMethod("unbindEmail")
	public String unbindEmail (String data) {
		EmailCode emailCode = JSONObject.parseObject(data, EmailCode.class);
		User user = userService.findById(ThreadLocalHelper.getClient().getUserId());
		if (!user.getMail().equals(emailCode.getEmail())) {
			return "-2";
		}
		String rightCode = ThreadLocalHelper.getClient().getServer()
				.getCodeByEmail(emailCode.getEmail());
		if (rightCode == null || !emailCode.getInputCode().equals(rightCode)) {
			return "-1";
		}
		// 移除验证码
		ThreadLocalHelper.getClient().getServer().removeVerificationCode(user.getMail());
		user.setId(ThreadLocalHelper.getClient().getUserId());
		user.setMail(null);
		userService.UpdateEmail(user);
		return "1";
	}
	
	@ResponseMethod
	public String forgetPwdCheckAccount (String data) {
		User user = userService.findByAccount(data);
		if (user == null) {
			return "0";
		}
		return "1";
	}
	
	/**
	 * 验证邮箱 -3：该账号未绑定任何邮箱，-2：邮箱错误，-1：验证码错误，1：解绑成功
	 * @param data
	 * @return
	 */
	@ResponseMethod
	public String forgetPwdCheckEmail (String data) {
		EmailCodeAndAccount e = JSONObject.parseObject(data, EmailCodeAndAccount.class);
		User user = userService.findByAccount(e.getAccount());
		if (user.getMail() == null || user.getMail().trim().isEmpty()) {
			return "-3";
		}
		if (!user.getMail().equals(e.getEmailCode().getEmail())) {
			return "-2";
		}
		String rightCode = ThreadLocalHelper.getClient().getServer()
				.getCodeByEmail(e.getEmailCode().getEmail());
		if (rightCode == null || !e.getEmailCode().getInputCode().equals(rightCode)) {
			return "-1";
		}
		// 移除验证码
		ThreadLocalHelper.getClient().getServer().removeVerificationCode(user.getMail());
		return "1";
	}
	
	/**
	 * 重置密码，1：修改成功，0：修改失败，非法访问，-1：密码不规范
	 * @param data
	 * @return
	 */
	@ResponseMethod
	public String forgetPwdResetPwd (String data) {
		ForgetPwdResetPwd f = JSONObject.parseObject(data, ForgetPwdResetPwd.class);
		if (!userService.checkPwd(f.getNewPwd())) {
			return "-1";
		}
		User user = userService.findByAccount(f.getAccount());
		if (user == null || !user.getMail().equals(f.getEmail())) {
			return "0";
		}
		User newUser = new User();
		newUser.setId(user.getId());
		newUser.setPassword(f.getNewPwd());
		userService.UpdateExcludeEmail(newUser);
		return "1";
	}
	
	/**
	 * 根据姓名搜索用户，参数为 页码数-搜索的名字
	 * @param data
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@ResponseMethod("findUserByName")
	public String findUserByName (String data) {
		PageWithData<String, FriendsVO> f = friendsService.findUserByName(JSONObject.parseObject(data, Page.class));
		if (f == null) {
			f = new PageWithData<String, FriendsVO>();
		}
		if (f.getData() == null) {
			f.setData(new ArrayList<FriendsVO>());
		}
		return JSONObject.toJSONString(f);
	}
}
